package com.zhuxulin.tab.threads;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.util.ArrayList;

import android.os.Process;

import com.zhuxulin.midi.MidiFile;
import com.zhuxulin.midi.event.MidiEvent;
import com.zhuxulin.midi.util.MidiEventListener;
import com.zhuxulin.midi.util.MidiProcessor;
import com.zhuxulin.midi.util.MidiUtil;
import com.zhuxulin.tab.App;
import com.zhuxulin.tab.bluetooth.ISendMsg;
import com.zhuxulin.tab.listeners.MidiListener2;
import com.zhuxulin.tab.utils.LogUtils;

public class PlayPiano extends Thread implements Runnable {

	private static final String TAG = PlayPiano.class.getSimpleName();
	private ISendMsg sendMsg = null;
	private MidiProcessor processor = null;
	private App app = null;
	private File midiFile = null;
	private boolean isStarted = false;
	private boolean isSet = false;
	private long lastMs = 0;
//	private byte[] cmd = null;
	private ByteBuffer buffer=ByteBuffer.allocate(2048);
	// private MidiEventListener listener = new MidiListener(app);
	private MidiEventListener listener = new MidiEventListener() {
		@Override
		public void onStop(boolean finished) {
			LogUtils.i(TAG, "onStop!Finished:" + finished);
		}

		@Override
		public void onStart(boolean fromBeginning) {
			LogUtils.i(TAG, "onStart!FromeBeginning:" + fromBeginning);
			sendMsg = app.getSendMsg();
		}

//		@Override
//		public void onEvent(MidiEvent event, long ms) {
//			if(event.getCmd()==null||event.getCmd().length<=0){
//				return;
//			}
//			/**
//			LogUtils.i(TAG, "ms:" + ms);
//			if (event == null) {
//				LogUtils.i(TAG, "event is null!");
//				// processor.stop();
//				return;
//			}
//			if (event.getCmd() == null) {
//				LogUtils.i(TAG, "cmd is null!");
//				// processor.stop();
//				return;
//			}*/
//			if ((sendMsg = app.getSendMsg()) == null) {
//				LogUtils.i(TAG, "SendMsg is null,plese connect it!");
//				processor.stop();
//				return;
//			}
//			if (lastMs == ms) {
//				buffer.put(event.getCmd());
////				cmd = MidiUtil.addByte(cmd, event.getCmd());
////				LogUtils.i(TAG, "prep:"+MidiUtil.bytesToHex(cmd));
//			} else {
//				lastMs = ms;
//				if(!isSet){
//					return;
//				}
//				isSet = true;
//				LogUtils.i(TAG, "BeginSendCmd");
//				/**
//				 * some times the same time is all FF events so this time cmd is null!
//				 */
////				if(cmd!=null&&cmd.length>0)sendMsg.sendMessage(cmd);
//				sendMsg.sendMessage(buffer.array(),0,buffer.position());
//				LogUtils.i(TAG, "send:"+MidiUtil.bytesToHex(buffer.array()));
////				LogUtils.i(TAG, "send:"+MidiUtil.bytesToHex(cmd));
//				LogUtils.i(TAG, "EndSendCmd");
////				cmd = null;
////				cmd = MidiUtil.addByte(cmd, event.getCmd());
////				LogUtils.i(TAG, "prep:"+MidiUtil.bytesToHex(cmd));
//				buffer.rewind();
//				buffer.clear();
//				buffer.put(event.getCmd());
//			}
//			// LogUtils.i(TAG, "BeginSendCmd");
//			// sendMsg.sendMessage(event.getCmd());
//			// LogUtils.i(TAG, "EndSendCmd");
//		}

		@Override
		public void onEvents(ArrayList<MidiEvent> events, long mMsElapsed) {
			byte[] bs = null;
			LogUtils.i(TAG, "ms:" + mMsElapsed);
			for (MidiEvent e : events) {
				bs = MidiUtil.addByte(bs, e.getCmd());
			}
			if (bs != null && bs.length >= 0) {
				sendMsg.sendMessage(bs);
			}
		}

		@Override
		public void onEvent(MidiEvent event, long ms) {
			if (event != null && event.getCmd() != null
					&& event.getCmd().length >= 0) {
				sendMsg.sendMessage(event.getCmd());
			}
		}
	};

	// public PlayPiano(ISendMsg sendMsg) {
	// this.sendMsg = sendMsg;
	// }

	public PlayPiano(App app, String fileName) {
		this(app, new File(fileName));
	}

	public PlayPiano(App app) {
		this.app = app;
		// listener = new MidiListener2(app);
		this.processor = app.getProcessor();
		// this(app,null);
		buffer.clear();
	}

	public PlayPiano(App app, File midiFile) {
		this.app = app;
		// this.sendMsg=app.getSendMsg();
		this.midiFile = midiFile;
		this.processor = app.getProcessor();
	}

	public PlayPiano setFile(File midiFile) {
		this.midiFile = midiFile;
		return this;
	}
	/**
	 * Just different from super.stop()
	 */
	public void Stop() {
		isStarted = false;
		processor.stop();
	}

	public boolean isStart() {
		return isStarted;
	}
	@Override
	public void run() {
		Process.setThreadPriority(Process.THREAD_PRIORITY_URGENT_AUDIO);
		isStarted = true;
		try {
			processor = new MidiProcessor(new MidiFile(midiFile));
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
		processor.registerEventListener(listener, MidiEvent.class);
		processor.start();
		/**
		if (processor == null) {
			try {
				processor = new MidiProcessor(new MidiFile(midiFile));
				app.setProcessor(processor);
				// processor = new MidiProcessor(new MidiFile(new File(
				// "/mnt/sdcard/Music/1.mid")));
			} catch (FileNotFoundException e) {
				e.printStackTrace();
			} catch (IOException e) {
				e.printStackTrace();
			}
			processor.registerEventListener(listener, MidiEvent.class);
			LogUtils.i(TAG, "Starting thread...");
			processor.start();
			LogUtils.i(TAG, "End thread...");
		} else if (processor.isStarted() || processor.isRunning()) {
			processor.stop();
			try {
				processor.setMidiFile(new MidiFile(midiFile));
			} catch (FileNotFoundException e) {
				e.printStackTrace();
			} catch (IOException e) {
				e.printStackTrace();
			}
			processor.registerEventListener(listener, MidiEvent.class);
			LogUtils.i(TAG, "Starting thread...");
			processor.start();
			LogUtils.i(TAG, "End thread...");
		}*/
	}
}
